package com.hwtx.form.domain.def.meta.config;

import cn.hutool.extra.spring.SpringUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.hwtx.form.annotation.Parameter;
import com.hwtx.form.domain.FormConstants;
import com.hwtx.form.domain.def.FormConfigExt;
import com.hwtx.form.domain.def.meta.Api;
import com.hwtx.form.domain.def.meta.Component;
import com.hwtx.form.domain.repo.ApiRepo;
import com.hwtx.form.domain.repo.FormConfigRepo;
import com.hwtx.form.domain.vo.FormData;
import com.hwtx.form.persistence.entity.ApiDef;
import com.hwtx.form.persistence.entity.FormConfigQuery;
import com.hwtx.form.util.FormUtil;
import com.hwtx.form.util.JacksonUtil;
import io.geekidea.boot.config.properties.BootProperties;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.autoconfigure.web.ServerProperties;

import java.util.List;
import java.util.Map;

import static com.hwtx.form.domain.FormConstants.HTTP_GET;
import static com.hwtx.form.util.FormUtil.*;

@Slf4j
@org.springframework.stereotype.Component
public class ApiSelectComponentConfig implements FormComponentConfig {

    public static final String API_DEF_CODE = "apiDefCode";
    @Resource
    private ServerProperties webApplicationContext;

    @Override
    public Map<String, Object> comExt(Map<String, Object> formData) {
        return getComponentParamInfo(formData);
    }

    @Override
    public ComponentParamInfo getInvokeComponentParamInfo(Map<String, Object> comExt) {
        if (comExt == null) {
            return null;
        }
        return getParamInfo(API_DEF_CODE, comExt);
    }

    @Override
    public Map<String, Object> getInputConfigParams(Map<String, Object> comExt, FormData formData) {
        Map<String, Object> ret = Maps.newHashMap();
        if (comExt == null) {
            return null;
        }
        String code = getStrPostValue(formData.getData(), API_DEF_CODE);
        if (StringUtils.isBlank(code)) {
            log.error("ApiSelectComponentConfig getInputConfigParams code is blank");
            return null;
        }
        ret.putAll(getInputComponentParamInfo(formData.getData(), API_DEF_CODE, comExt));
        ret.putAll(getFieldsData(formData.getData()));
        return ret;
    }

    @Override
    public OutputConfig getOutputConfigParams(String type, FormConfigExt.FormConfigCtr formConfigCtr) {
        Map<String, Object> ret = getParamInfoCode(formConfigCtr, Map.of(API_DEF_CODE, true));
        Map<String, Object> comExt = formConfigCtr.getComExt();
        if (comExt != null) {
            if (comExt.containsKey(FIELDS)) {
                ret.put(FIELDS, comExt.get(FIELDS));
            }
            if (comExt.containsKey(F_TABLE)) {
                ret.put(F_TABLE, comExt.get(F_TABLE));
            }
        }
        return OutputConfig.builder().params(ret).notIncludeKeys(List.of("comExt", "configCtr")).build();
    }

    @Override
    public String getConfig(String type, Map<String, Object> formData) {
        BootProperties bootProperties = SpringUtil.getBean(BootProperties.class);
        String domain = bootProperties.getDomain();
        if (formData.containsKey(API_DEF_CODE)) {
            List<Component> formBody = Lists.newArrayList();
            String apiDefCode = getStrPostValue(formData, API_DEF_CODE);
            if (StringUtils.isNotBlank(apiDefCode)) {
                formBody.addAll(getComponentParamsConfig(apiDefCode, API_DEF_CODE, formData));
            }
            return buildInputOutputConfig(domain, formBody, FormUtil.getUrlContext(webApplicationContext));
        }
        Long id = getLongPostValue(formData, "id");
        String code = null;
        if (id != null) {
            FormConfigQuery formConfigQuery = SpringUtil.getBean(FormConfigRepo.class).getFormConfigQuery(id);
            if (formConfigQuery == null) {
                throw new RuntimeException("未找到表单配置 id=" + id);
            }
            FormConfigExt formConfigExt = FormUtil.getFormConfigExt(formConfigQuery.getExt());
            if (formConfigExt != null && type != null) {
                FormConfigExt.FormConfigCtr configCtr = FormUtil.getFormConfigCtr(type, formConfigExt);
                if (configCtr != null && configCtr.getComExt() != null) {
                    ComponentParamInfo componentParamInfo = FormComponentConfig.getParamInfo(configCtr.getComExt().get(API_DEF_CODE));
                    if (componentParamInfo != null) {
                        code = componentParamInfo.code;
                    }
                }
            }
        }
        boolean includeFields = false;
        if (code != null) {
            ApiDef apiDef = SpringUtil.getBean(ApiRepo.class).getApiDef(code);
            if (apiDef != null) {
                if (apiDef.getExt() != null) {
                    List<Parameter> parameters = getActionParameters(apiDef);
                    includeFields = CollectionUtils.isNotEmpty(parameters) && parameters.size() > 1;
                }
            }
        }
        List<Component> controls = Lists.newArrayList();
        Component.Select select = FormComponentConfig.getApiSelect(domain, "服务配置", "请选择服务",
                API_DEF_CODE, API_DEF_CODE, "${event.data." + API_DEF_CODE + "}", includeFields,
                Api.builder().method(HTTP_GET).url(domain + getUrlContext(webApplicationContext) + FormConstants.API_DEF_API).build(),
                getUrlContext(webApplicationContext));
        controls.add(select);
        List<Component.Select> fieldsSelect = FormComponentConfig.getFieldSelect(bootProperties.getDomain(), getStrPostValue(formData, "modelName"), getUrlContext(webApplicationContext));
        Component.Group group = new Component.Group();
        group.setId(G_FIELDS);
        group.setVisibleOn(includeFields ? "true" : "false");
        group.setBody(Lists.newArrayList(fieldsSelect));
        controls.add(group);
        return JacksonUtil.object2json(controls);
    }
}
